Conversation
…ding A dash is the cheapest way to mint a near-miss of an ending someone else holds. `.crypto` and `.cryp-to` read as the same thing at a glance and sort next to each other, so allowing dashes turns every claimed ending into a family of look-alikes worth squatting. The namespace is one level deep and first come first served: there is no second level to retreat to and no dispute process to appeal into, which makes the near-miss the whole attack rather than a nuisance. Blast radius measured before changing anything: of 4593 endings claimed, exactly one contains a dash — `.lazy-loaded`, minted today while testing whether dashes were allowed. Nothing else in the namespace moves. The rule is changed in both places at once on purpose. A name the bridge accepts and the registry rejects resolves to a page saying it does not exist, which is a worse failure than either rule alone. The cost is real names nobody can have. That is the trade, and it is cheaper than policing look-alikes forever. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
This was referenced Aug 1, 2026
ralyodio
added a commit
to profullstack/tronbrowser.dev
that referenced
this pull request
Aug 1, 2026
…try (#66) Both local copies of the name grammar accepted a dash inside a label, which the registry is dropping (moshcoder/moshpit-name#6, moshcoder/moshcode#193). A name accepted here and rejected there forwards the tab to a page saying it does not exist, which is a worse failure than refusing it up front. Neither drift test would have caught this. moshpit.test.js compares the extension port against the TypeScript reference over a shared hostname list, and moshpit-drift.test.js compares both against the published package — and neither list contained a dash inside a label. Leading and trailing dashes were covered from the start; the case the rule actually turns on was covered nowhere, so all three implementations could disagree and every assertion still passed. Both lists now carry it, and the anchor consequently fails against @moshcoder/moshpit-resolve 0.1.1 with a real behavioural difference: blue.lazy-loaded decides 'park' against the package and 'clearnet' here. That is the guard working. It goes green once moshcoder/moshpit-resolve#3 publishes and the devDependency is bumped. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio
added a commit
to moshcoder/moshpit-dns
that referenced
this pull request
Aug 1, 2026
The last copy of this rule, and right now the one breaking main in moshcode: with moshcoder/moshcode#193 and #194 merged, its drift test compares the vendored bridge against this package and fails on blue.lazy-loaded — vendored says null, this says { blue, lazy-loaded }. That is the guard working. It was predicted in #194 and is why the publish has to lead the consumer, not follow it. Matches moshcoder/moshpit-name#6 and moshcoder/moshpit-resolve#3. Of 4593 endings claimed, exactly one contains a dash. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio
added a commit
to moshcoder/moshpit-resolve
that referenced
this pull request
Aug 1, 2026
A dash is the cheapest way to mint a near-miss of an ending someone else holds. `.crypto` and `.cryp-to` read as the same thing at a glance, and this namespace is one level deep and first come first served, so there is no second level to retreat to and nothing to appeal into. Matches moshcoder/moshpit-name#6 and moshcoder/moshcode#193. This copy came to light because tronbrowser.dev anchors both of its local copies to this package: with the rule changed there and not here, the anchor test fails with a real behavioural difference — `blue.lazy-loaded` decides 'park' against this package and 'clearnet' against the new rule, which is a tab sent somewhere else. Blast radius, measured against the live registry: of 4593 endings claimed, exactly one contains a dash. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio
added a commit
that referenced
this pull request
Aug 1, 2026
Unblocks main, which has been red since #193 merged. The dash rule landed here (#193) and in the drift guard covering it (#194) before the package carried it, so dns-drift correctly failed on blue.lazy-loaded: vendored null, published { blue, lazy-loaded }. That is the guard working. 0.2.2 carries the rule. The lockfile is the part that matters — CI runs `pnpm install --frozen-lockfile`, so the ^0.2.1 range in package.json never picked the new version up on its own; it installed 0.2.1 and kept failing after the publish. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A dash is the cheapest way to mint a near-miss of an ending someone else holds.
.cryptoand.cryp-toread as the same thing at a glance and sort next to each other.That matters more here than it would elsewhere: the namespace is one level deep and first come first served. There's no second level to retreat to and no dispute process to appeal into, so a look-alike isn't a nuisance — it's the whole attack.
Blast radius, measured before changing anything
Of 4,593 endings currently claimed, exactly one contains a dash:
— minted today while testing whether dashes were allowed. Nothing else in the namespace moves.
The rule
Changed in both places at once, deliberately:
apps/pwa/src/lib/moshpit-name.mjs(the registry, authoritative) andsrc/dns.mjs(parseRegistryName, the bridge). A name the bridge accepts and the registry rejects resolves to a page saying it does not exist — worse than either rule alone.Unchanged: all-numeric endings (
.420), all-numeric labels (123.420), the 63-character ceiling, and leading/trailing-dash rejection (now by construction).Tests
One existing assertion encoded the old rule (
normalizeTld("web3-agents")) and moved to the rejection case, which is the behaviour change showing up where it should.Before merge
Two follow-ups this doesn't do:
.lazy-loadedbecomes unparseable once this lands — its page and any management of it break. It should be released first, or grandfathered. It's the only one.@moshcoder/moshpit-dnsandmoshcoder/moshpit-namecarry their own copies of this regex and will drift until they get the same change.🤖 Generated with Claude Code